#include <qqtfindservermanager.h>

#include <qqthostaddressmanager.h>
#include <qqtframe.h>

enum MsgSecName
{
    CMD_TYPE = 0,
    CMD_CONTENT,
    CMD_MAX
};

QQtBeServerManager::QQtBeServerManager ( QObject* parent )
    : QObject ( parent )
{
    s0 = new QQtUdpServer ( this );
    m0 = new QQtBeServerProtocolManager ( this );
    m0->registerProtocol<QQtBeServerProtocol>();
    s0->installProtocolManager ( m0 );

    QQtHostAddressManager manager;
    QString ip = manager.getHostAddress();
    int port = 4408;
#if USE_HOST_ADDRESS
    s0->bind ( QHostAddress ( ip ), port, QQtUdpServer::DefaultForPlatform );
#else
    s0->bind ( port, QQtUdpServer::DefaultForPlatform );
#endif
    p3line() << s0->localAddress() << s0->localPort();

    //设置告知client的服务器信息。
    //setTellClient ( s0->localAddress().toString(), 5500 );
    //setTellClient ( "192.168.2.165", 5500 );
    setTellClient ( ip, 5500 );
}

QQtBeServerManager::~QQtBeServerManager() {}

void QQtBeServerManager::setListeningAddress ( QHostAddress address, int port )
{
    s0->disconnectFromHost();
    s0->bind ( address, port, QQtUdpServer::DefaultForPlatform );
    p3line() << s0->localAddress() << s0->localPort();
}

void QQtBeServerManager::setListeningPort ( int port )
{
    s0->disconnectFromHost();

    QQtHostAddressManager manager;
    QString ip = manager.getHostAddress();

#if USE_HOST_ADDRESS
    s0->bind ( QHostAddress ( ip ), port, QQtUdpServer::DefaultForPlatform );
#else
    s0->bind ( port, QQtUdpServer::DefaultForPlatform );
#endif
    p3line() << s0->localAddress() << s0->localPort();
}

void QQtBeServerManager::setTellClient ( QString ip, int port )
{
    mIP = ip;
    mPort = port;
    m0->setLocalIpPort ( ip, port );
    p3line() << ip << port;
}

QString QQtBeServerManager::tellClientIP()
{
    return mIP;
}

int QQtBeServerManager::tellClientPort()
{
    return mPort;
}

QQtFindServerManager::QQtFindServerManager ( QObject* parent )
    : QObject ( parent )
{
    c0 = new QQtUdpClient ( this );
    p0 = new QQtFindServerProtocol ( this );
    c0->installProtocol ( p0 );

    connect ( p0, SIGNAL ( signalFindServer ( QString, int ) ),
              this, SIGNAL ( signalFindServer ( QString, int ) ) );

    QQtHostAddressManager manager;
    QString ip = manager.getHostAddress();
    int port = 4409;
#if USE_HOST_ADDRESS
    c0->bind ( QHostAddress ( ip ), port, QQtUdpClient::DefaultForPlatform );
#else
    c0->bind ( port, QQtUdpClient::DefaultForPlatform );
#endif
    p3line() << c0->localAddress() << c0->localPort();

    c0->setServerAddress ( QHostAddress ( QHostAddress::Broadcast ), 4408 );
}

QQtFindServerManager::~QQtFindServerManager() {}

void QQtFindServerManager::setServerPort ( int port )
{
    c0->setServerAddress ( QHostAddress ( QHostAddress::Broadcast ), port );
    p3line() << QHostAddress ( QHostAddress::Broadcast ) << port;
}

void QQtFindServerManager::setLocalAddress ( QHostAddress address, int port )
{
    c0->disconnectFromHost();
    c0->bind ( address, port, QQtUdpClient::DefaultForPlatform );
    p3line() << c0->localAddress() << c0->localPort();
}

void QQtFindServerManager::setLocalPort ( int port )
{
    c0->disconnectFromHost();
    QQtHostAddressManager manager;
    QString ip = manager.getHostAddress();
#if USE_HOST_ADDRESS
    c0->bind ( QHostAddress ( ip ), port, QQtUdpClient::DefaultForPlatform );
#else
    c0->bind ( port, QQtUdpClient::DefaultForPlatform );
#endif
    p3line() << c0->localAddress() << c0->localPort();
}

void QQtFindServerManager::sendFindServer()
{
    p0->sendFindServerRequest();
}

QQtBeServerProtocolManager::QQtBeServerProtocolManager ( QObject* parent )
    : QQtProtocolManager ( parent ) {}

QQtBeServerProtocolManager::~QQtBeServerProtocolManager() {}

void QQtBeServerProtocolManager::setLocalIpPort ( QString ip, int port )
{
    mIP = ip;
    mPort = port;
}

QQtProtocol* QQtBeServerProtocolManager::createProtocol()
{
    QQtBeServerProtocol* p = ( QQtBeServerProtocol* ) QQtProtocolManager::createProtocol();
    p->setLocalIpPort ( mIP, mPort );
    return p;
}

QQtBeServerProtocol::QQtBeServerProtocol ( QObject* parent )
    : QQtDataProtocol ( parent ) {}

QQtBeServerProtocol::~QQtBeServerProtocol()
{

}

void QQtBeServerProtocol::setLocalIpPort ( QString ip, int port )
{
    mIP = ip;
    mPort = port;
}

void QQtBeServerProtocol::sendBeServerMessage()
{
    QQtDataSerialization data;
    data[CMD_TYPE] = "server_ack";
    data[CMD_CONTENT]["ip"] = mIP;
    data[CMD_CONTENT]["port"] = mPort;
    data.serialize();
    p3line() << data[CMD_TYPE].getValue().toString() << mIP << mPort;
    sendMessage ( data );
}

void QQtBeServerProtocol::recvMessage ( const QQtDataSerialization& data )
{
    QQtDataSerialization ds0 = data;
    QString cmd_type = ds0[CMD_TYPE].getValue().toString();
    p3line() << cmd_type;
    if ( cmd_type == "find_server" )
    {
        sendBeServerMessage();
    }
}

QQtFindServerProtocol::QQtFindServerProtocol ( QObject* parent )
    : QQtDataProtocol ( parent ) {}

QQtFindServerProtocol::~QQtFindServerProtocol()
{

}

void QQtFindServerProtocol::sendFindServerRequest()
{
    QQtDataSerialization data;
    data[CMD_TYPE] = "find_server";
    data.serialize();
    p3line() << data[CMD_TYPE].getValue().toString();
    sendMessage ( data );
}

void QQtFindServerProtocol::recvMessage ( const QQtDataSerialization& data )
{
    QQtDataSerialization ds0 = data;
    QString cmd_type = ds0[CMD_TYPE].getValue().toString();
    p3line() << cmd_type;
    if ( cmd_type == "server_ack" )
    {
        QQtDictionary& ct0 = ds0[CMD_CONTENT];
        mIP = ct0["ip"].getValue().toString();
        mPort = ct0["port"].getValue().toInt();
        p3line() << mIP << mPort;
        emit signalFindServer ( mIP, mPort );
    }
}
